import { Button, Input, Select, Tag } from "@specialdoom/solid-rev-kit"
import axios from "axios";
import { Setter } from "solid-js";

type RequestResultType = Record<string, any> | string

const httpTypes: { label: string; value: string; }[] = ['GET', 'POST', 'PUT', 'DELETE'].map(it => ({ label: it, value: it }))
type TableTypes = 'Header' | 'Params' | 'Body'
type ColumnType = {
  param: string;
  value: string;
}
const defaultTableData: ColumnType[] = [
  {
    param: '',
    value: ''
  }
]

type BodyType = 'none' | 'raw' | 'json' | 'xml'
const bodyTypeSelectOptions = ['none', 'raw', 'json', 'xml'].map(it => ({ label: it, value: it }))

export default function Index() {
  const [httpType, setHttpType] = createSignal('GET')
  const [url, setUrl] = createSignal('')
  const [queryResult, setQueryResult] = createSignal<RequestResultType>()

  const [queryHeaders, setQueryHeaders] = createSignal(defaultTableData)
  const [queryParams, setQueryParams] = createSignal(defaultTableData)
  const [queryBody, setQueryBody] = createSignal('')

  const [queryHeaderInputs, setQueryHeaderInputs] = createSignal(defaultTableData.map(() => 0))
  const [queryParamInputs, setQueryParamInputs] = createSignal(defaultTableData.map(() => 0))

  const [bodyType, setBodyType] = createSignal<BodyType>('none')

  createEffect(() => {
    if (queryHeaders().length !== queryHeaderInputs().length) {
      setQueryHeaderInputs(Array(queryHeaders().length).fill(0))
    }
  })

  createEffect(() => {
    if (queryParams().length !== queryParamInputs().length) {
      setQueryParamInputs(Array(queryParams().length).fill(0))
    }
  })

  const [tableType, setTableType] = createSignal<TableTypes>('Params')
  const rerender = (render: Setter<ColumnType[]>) => render(defaultTableData)
  function setParamByIndex(idx: number, content: string, key: 'param' | 'value') {
    setQueryParams(prev => {
      prev[idx][key] = content
      return [...prev]
    })
  }
  function setHeaderByIndex(idx: number, content: string, key: 'param' | 'value') {
    setQueryHeaders(prev => {
      prev[idx][key] = content
      return [...prev]
    })
  }

  function handleRequest() {
    console.log(url(), httpType())
    const params: Record<string, string> = {}
    const headers: Record<string, string> = {}
    queryParams().forEach(it => {
      params[it.param] = it.value
    })
    queryHeaders().forEach(it => {
      headers[it.param] = it.value
    })
    axios<RequestResultType>(url(), {
      method: httpType(),
      params: queryParams().length === 0 ? {} : params,
      data: bodyType() !== 'none' ? queryBody() : null
    }).then(res => {
      console.log('result', res)
      setQueryResult(res.data)
    })
  }
  return (
    <div class="flex justify-center bg-blend-hard-light py-3 h-500px">
      <div>
        <div class="space-y-2">
          <div class="flex justify-center items-center space-x-2 rounded shadow-md bg-white px-3 py-2">
            <Select options={httpTypes} defaultOption='GET' onSelect={opt => setHttpType(opt)} />
            <Input placeholder="http://example.com:8080" value={url()} onInput={(e: any) => setUrl(e.currentTarget.value)} />
            <Button onClick={handleRequest}>Request</Button>
          </div>
          <div class="flex flex-col justify-center mb-2">
            <div class="flex justify-center space-x-2">
              <Switch>
                <Match when={tableType() === 'Header'}>
                  <div onClick={() => setTableType('Params')}><Tag type="bright" color="accent">Params</Tag></div>
                  <div onClick={() => setTableType('Header')}><Tag type="accent" color="bright">Headers</Tag></div>
                  <div onClick={() => setTableType('Body')}><Tag type="bright" color="accent">Body</Tag></div>
                </Match>
                <Match when={tableType() === 'Params'}>
                  <div onClick={() => setTableType('Params')}><Tag type="accent" color="bright">Params</Tag></div>
                  <div onClick={() => setTableType('Header')}><Tag type="bright" color="accent">Headers</Tag></div>
                  <div onClick={() => setTableType('Body')}><Tag type="bright" color="accent">Body</Tag></div>
                </Match>
                <Match when={tableType() === 'Body'}>
                  <div onClick={() => setTableType('Params')}><Tag type="bright" color="accent">Params</Tag></div>
                  <div onClick={() => setTableType('Header')}><Tag type="bright" color="accent">Headers</Tag></div>
                  <div onClick={() => setTableType('Body')}><Tag type="accent" color="bright">Body</Tag></div>
                </Match>
              </Switch>
            </div>
            <div class="flex justify-center my-2 bg-white py-3 rounded-xl shadow-md">
              <Switch >
                <Match when={tableType() === 'Header'}>
                  <table>
                    <thead>
                      <tr>
                        <th>Params</th>
                        <th>Value</th>
                      </tr>
                    </thead>
                    <tbody>
                      <For each={queryHeaderInputs()}>
                        {(_, idx) => (
                          <tr>
                            <td>
                              <div class="mx-1">
                                <Input value={queryHeaders()[idx()].param} onInput={(e: any) => setHeaderByIndex(idx(), e.currentTarget.value, 'param')} />
                              </div>
                            </td>
                            <td>
                              <div class="mx-1">
                                <Input value={queryHeaders()[idx()].value} onInput={(e: any) => setHeaderByIndex(idx(), e.currentTarget.value, 'value')} />
                              </div>
                            </td>
                          </tr>
                        )}
                      </For>
                    </tbody>
                  </table>
                </Match>
                <Match when={tableType() === 'Params'}>
                  <table>
                    <thead>
                      <tr>
                        <th>Params</th>
                        <th>Value</th>
                      </tr>
                    </thead>
                    <tbody>
                      <For each={queryParamInputs()}>
                        {(_, idx) => (
                          <tr>
                            <td>
                              <div class="mx-1">
                                <Input value={queryParams()[idx()].param} onInput={(e: any) => setParamByIndex(idx(), e.currentTarget.value, 'param')} />
                              </div>
                            </td>
                            <td>
                              <div class="mx-1">
                                <Input value={queryParams()[idx()].value} onInput={(e: any) => setParamByIndex(idx(), e.currentTarget.value, 'value')} />
                              </div>
                            </td>
                          </tr>
                        )}
                      </For>
                    </tbody>
                  </table>
                </Match>
                <Match when={tableType() === 'Body'}>
                  <div class="flex flex-col justify-center">
                    <Select options={bodyTypeSelectOptions} defaultOption="none" onSelect={(v) => setBodyType(v as BodyType)} />
                    <textarea
                      class="px-4 py-2 w-250px bg-transparent outline-none outline-active:none border border-rounded border-gray-200 border-dark:gray-700"
                      value={queryBody()}
                      onInput={(e) => setQueryBody(e.currentTarget.value)}
                    />
                  </div>
                </Match>
              </Switch>
            </div>
          </div>
          <div class="flex justify-center">
            <div class="flex text-center rounded-xl shadow-md bg-dark h-250px break-words text-white w-100 p-2">
              <pre>{!!queryResult() ? JSON.stringify(queryResult(), null, 2) : ''}</pre>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}
